//! 若正确使用此模块，则
//! 1. 将定时任务要执行的函数注册到`JOB_FUNCTIONS`中，即调用[register]方法
//! 2. 调用[scheduled::save_scheduled]方法保存定时任务并开启定时任务
//! 3. 调用[scheduled::delete_scheduled]方法删除定时任务并取消定时任务
//! 4. 项目启动时会调用[scheduled::init_scheduler]方法查询所有的定时任务并开启定时任务
//!
//! > [scheduled] 中的`task`属性就是[register]方法中的`task_id`参数
//!
//! # Example
//! ```
//! pub fn foo(id: i64) -> BoxFuture {
//!     Box::pin(async move {
//!         log::info!("foo:{id}")
//!     })
//! }
//! #[tokio::main]
//! async fn main() {
//!     let task_id = func_path!(foo).to_string();
//!     register(task_id, foo);
//!     let scheduled = Scheduled {
//!         business_id: 1,
//!         business_type: None,
//!         cron: Some("*/1 * * * * *".to_string()),
//!         task: task_id,
//!         start_time: None,
//!     };
//!     save_scheduled(scheduled).await.unwrap();
//! }
//! ```
use dashmap::DashMap;
use std::pin::Pin;
use std::sync::LazyLock;
use tokio_cron_scheduler::JobScheduler;

pub mod prelude;
pub mod scheduled;
pub mod system_scheduled;

pub type BoxFuture<O = ()> = Pin<Box<dyn Future<Output = O> + Send>>;
pub type JobFunction = fn(i64) -> BoxFuture;

static JOB_FUNCTIONS: LazyLock<DashMap<String, JobFunction>> = LazyLock::new(|| DashMap::with_capacity(32));

static SCHEDULER: LazyLock<DashMap<i64, JobScheduler>> =
    LazyLock::new(|| DashMap::with_capacity(32));

/// 注册函数
///
/// `task_id`：为[JobFunction]的唯一标识, 也是[save_scheduled]方法参数中的`task`属性
/// `function`：为定时任务要执行的函数
pub fn register(task_id: String, function: JobFunction) -> Option<JobFunction> {
    JOB_FUNCTIONS.insert(task_id, function)
}
